package com.models.shiro;

import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ShiroConfig {
	
	/**
	 * 设置全局缓存变量
	 * */
	
	public static Long expireTime = 60000000L;
	
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();//获取filters
		filters.put("authc", new CustomFormAuthenticationFilter());
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl("/login");
      
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/ajaxLogin", "anon");
        filterChainDefinitionMap.put("/logout", "logout");
        filterChainDefinitionMap.put("/**", "authc");
        
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager securityManager(@Qualifier("hashedCredentialsMatcher") HashedCredentialsMatcher matcher) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm.
        securityManager.setRealm(jdbcShiroRealm(matcher));
        // session管理器  
        securityManager.setSessionManager(sessionManager());
        securityManager.setCacheManager(redisCacheManager());
        return securityManager;
    }
    
    @Bean
    public RedisSessionDao redisSessionDao() {
    	RedisSessionDao redisSessionDao = new RedisSessionDao();
    	//redisSessionDao.setExpire(1800000);
    	redisSessionDao.setExpire(expireTime);
    	return redisSessionDao;
    }
    
    @Bean
    public RedisCacheManager redisCacheManager() {
    	RedisCacheManager redisCacheManager = new RedisCacheManager();
    	redisCacheManager.setExpire(expireTime);
        return redisCacheManager;
    }
   
    @Bean
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionDAO(redisSessionDao());
        sessionManager.setGlobalSessionTimeout(redisSessionDao().getExpire());
        sessionManager.setCacheManager(redisCacheManager());
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        return sessionManager;
    }
    
   

    /**
     * 身份认证realm; (这个需要自己写，账号密码校验；权限等)
     * 
     * @return
     */
    @Bean
    public JdbcShiroRealm jdbcShiroRealm(HashedCredentialsMatcher matcher) {
    	JdbcShiroRealm jdbcShiroRealm = new JdbcShiroRealm();
    	jdbcShiroRealm.setCredentialsMatcher(matcher);
    	jdbcShiroRealm.setCachingEnabled(true);
    	jdbcShiroRealm.setAuthorizationCachingEnabled(true);
    	//jdbcShiroRealm.setAuthenticationCachingEnabled(true);
        return jdbcShiroRealm;
    }
    
    
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
    
    
    @Bean(name = "hashedCredentialsMatcher")
    public HashedCredentialsMatcher hashedCredentialsMatcher() {
    	
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");// 散列算法:这里使用MD5算法;
        hashedCredentialsMatcher.setHashIterations(1024);// 散列的次数，比如散列两次，相当于
        return hashedCredentialsMatcher;
    }
    
    
    
   /* @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }*/
    
    
  /*  @Bean
    public HandlerExceptionResolver handlerExceptionResolver() {  
        return new ShiroExceptionHandler();  
    }  */
}

